package Java_Concurrency_in_Practice.c9_3_2;

import java.util.concurrent.*;

/*
 * 支持取消, 完成通知以及进度通知的后台任务类
 */
abstract class BackgroundTask<V> implements Runnable, Future<V> {
    private final FutureTask<V> computation = new Computation();

    private class Computation extends FutureTask<V> {

        public Computation() {
            super(new Callable<V>() {
                @Override
                public V call() throws Exception {
                    return BackgroundTask.this.compute();
                }
            });
        }

        protected final void done() {
            GuiExecutor.getInstance().execute(new Runnable() {
                @Override
                public void run() {
                    V value = null;
                    Throwable thrown = null;
                    boolean cancelled = false;
                    try {
                        value = get();
                    } catch (CancellationException e) {
                        cancelled = true;
                    } catch (InterruptedException consumed) {

                    } catch (ExecutionException e) {
                        thrown = e.getCause();
                    } finally {
                        onCompletion(value, thrown, cancelled);
                    }


                }
            });
        }

        protected void setProgress(final int current, final int max) {
            GuiExecutor.getInstance().execute(new Runnable() {
                @Override
                public void run() {
                    onProgress(current, max);
                }
            });
        }
    }

    // 在后台线程中被取消
    protected abstract V compute() throws Exception;

    // 在事件线程中被取消
    protected void onCompletion(V result, Throwable exception, boolean cancelled) {

    }

    protected void onProgress(int current, int max) {}
}
